WordPress-Gallery using Bootstrap without a plugin

July 11, 2017 by flynxify

So, you are using a WordPress-theme that was built with Bootstrap 3? That’s neat! But the moment you try to use some of your CMS’s built-in features to spice up your articles and pages you run into some issues – specifically that WordPress uses markup that clashes with how Bootstrap runs things. Specifically – galleries. A child could click together a gallery using the backend and and TinyMCE but what will happen in your frontend is usually going to be a disaster.

There is an easier way – we could simply use Bootstraps Rows and Columns to create a responsive and highly customizable gallery while still using WordPress’s built-in tools to create it. This is especially helpful if you want to save a few MB’s of ram on your server by not installing a plugin that would do exactly that or something along those lines.

All we need is your functions.php and some time. But before we do, some basics about Bootstrap’s grid-system. As you may already know, columns are represented by DIV-containers with the classes “col-*-*”. They are nested in another DIV with the class “row”:


<div class="row"> <div class="col-md-1">.col-md-1</div> <div class="col-md-1">.col-md-1</div> [...] </div> <div class="row"> <div class="col-md-8">.col-md-8</div> <div class="col-md-4">.col-md-4</div> </div> <div class="row"> <div class="col-md-4">.col-md-4</div> <div class="col-md-4">.col-md-4</div> <div class="col-md-4">.col-md-4</div> </div> <div class="row"> <div class="col-md-6">.col-md-6</div> <div class="col-md-6">.col-md-6</div> </div>

(Taken from getbootstrap.com)

The Bootstrap-grid has enough room for 12 columns in total. That gives us plenty of room to fit a number of thumbnails into the width of our viewport, that eventually form a gallery.

But first we take a look at what we work with. This is what a gallery of images looks like in WordPress’ standard theme “Twenty Fifteen”:

A regular WordPress-Gallery.

The corresponding HTML-lookup looks like that:


<div id="gallery" class="gallery galleryid-112 gallery-columns-3 gallery-size-thumbnail">
    <figure class="gallery-item">
        <div class="gallery-icon landscape">
            <a href="x.jpg">
                <img src="x.jpg" alt="x" class="attachment-thumbnail size-thumbnail" height="150" width="150">
            </a>
        </div>
    </figure>
    <figure class="gallery-item">
        [...]
    </figure>
</div>

On a glance: trying to mess around with CSS solely to apply Bootstrap-logic to this construct would be quite the challenge. It would be far easier to just re-write the entire thing – which is exactly what we are going to do.

Re-writing the output

As the gallery is a built-in function of WordPress we have to use a little bit of PHP to squeeze whatever the system gives us into corresponding rows/columns. The best place to do that is your themes functions.php! This is the function we are going to use:


add_filter( 'post_gallery', 'bootstrap_gallery', 10, 3 );

function bootstrap_gallery( $output = '', $atts, $instance ) {
    $atts = array_merge(array('columns' => 3), $atts);
    
    $columns = $atts['columns'];
    $images = explode(',', $atts['ids']);
    $col_class = 'col-xs-4 col-sm-4 col-md-3 col-lg-3';
    
    $return = '<div class="gallery-box"><div class="row">';
    
    $i = 0;
    
    foreach ($images as $key => $value) {

        $image_attributes_thumbnail = wp_get_attachment_image_src($value, 'bootstrap_gallery_size');
        $image_attributes_fullsize = wp_get_attachment_image_src($value, 'full');
        $image_alt = get_post_meta($value, '_wp_attachment_image_alt', true);
        $image_title = get_the_title($value);
        $meta = wp_get_attachment_metadata($value);

        $return .= '
        <div class="'.$col_class.' gallery-img">
            <p>
                <a class="fancybox" title="'.$image_title.'" data-gallery="gallery" rel="gallery-'. $instance .'" href="'.$image_attributes_fullsize[0].'">
                    <img src="'.$image_attributes_thumbnail[0].'" width="'.$image_attributes_thumbnail[1].'" height="'.$image_attributes_thumbnail[2].'" alt="'.$image_alt.'" title="'.$image_title.'" class="img-responsive">
                </a>
            </p>
        </div>';
        
        $i++;
    }
    
    $return .= '</div></div>';
    
    return $return;
}

And this is what you end up with HTML-wise:


<div class="gallery-box">
    <div class="row">
        <div class="col-xs-4 col-sm-4 col-md-3 col-lg-3">
            <p>
                <a title="x" rel="gallery-x" href="x.jpg">
                    <img src="x.jpg" alt="x" title="x" class="img-responsive" height="x" width="x">
                </a>
            </p>
        </div>
        <div class="col-xs-4 col-sm-4 col-md-3 col-lg-3">
            [...]
        </div>
    </div>
</div>

Which is some nice, clean and, most-importantly, Bootstrap-ready markup. The same gallery will end up looking a little something like this in a theme that uses the framework:

The same WordPress-Gallery using Bootstrap-markup.

The same WordPress-Gallery using Bootstrap-markup.
The same WordPress-Gallery using Bootstrap-markup.

Additional uses

This gives you plenty of advantages! Not just the aformentioned indepence of plugins that would give you a similar output; the little PHP-function is not terribly long or complicated. If you need to add more classes, ID’s other elements to the gallery itself or its elements you are pretty much free to do so.

For example – I am using Fancybox2 as a lightbox. Fancybox2 comes with an option to not just open images individually, but also treat multiple images as a gallery which you can easily click through. The only thing the jQuery-plugin needs is an added class to your <a>-tag and a common rel-attribute that distinguishes one gallery from another one on your page. To achieve that, simply modify your function to look like this:


<a class="fancybox" title="'.$image_title.'" rel="gallery-'. $instance .'" href="'.$image_attributes_fullsize[0].'">

This will give your galleries <a>-tags with unique rel-attributes.